export default function (self) {
  "use strict";

  const kTestChars = "ABC~‾¥≈¤･・•∙·☼★星🌟星★☼·∙•・･¤≈¥‾~XYZ";

  // formDataPostFileUploadTest - verifies multipart upload structure and
  // numeric character reference replacement for filenames, field names,
  // and field values using FormData and fetch().
  //
  // Uses /fetch/api/resources/echo-content.py to echo the upload
  // POST (unlike in send-file-form-helper.js, here we expect all
  // multipart/form-data request bodies to be UTF-8, so we don't need to
  // escape controls and non-ASCII bytes).
  //
  // Fields in the parameter object:
  //
  // - fileNameSource: purely explanatory and gives a clue about which
  //   character encoding is the source for the non-7-bit-ASCII parts of
  //   the fileBaseName, or Unicode if no smaller-than-Unicode source
  //   contains all the characters. Used in the test name.
  // - fileBaseName: the not-necessarily-just-7-bit-ASCII file basename
  //   used for the constructed test file. Used in the test name.
  const formDataPostFileUploadTest = ({ fileNameSource, fileBaseName }) => {
    promise_test(async (testCase) => {
      const formData = new FormData();
      let file = new Blob([kTestChars], { type: "text/plain" });
      try {
        // Switch to File in browsers that allow this
        file = new File([file], fileBaseName, { type: file.type });
      } catch (ignoredException) {}

      // Used to verify that the browser agrees with the test about
      // field value replacement and encoding independently of file system
      // idiosyncracies.
      formData.append("filename", fileBaseName);

      // Same, but with name and value reversed to ensure field names
      // get the same treatment.
      formData.append(fileBaseName, "filename");

      formData.append("file", file, fileBaseName);

      const formDataText = await (
        await fetch(`/fetch/api/resources/echo-content.py`, {
          method: "POST",
          body: formData,
        })
      ).text();
      const formDataLines = formDataText.split("\r\n");
      if (formDataLines.length && !formDataLines[formDataLines.length - 1]) {
        --formDataLines.length;
      }
      assert_greater_than(
        formDataLines.length,
        2,
        `${fileBaseName}: multipart form data must have at least 3 lines: ${JSON.stringify(
          formDataText
        )}`
      );
      const boundary = formDataLines[0];
      assert_equals(
        formDataLines[formDataLines.length - 1],
        boundary + "--",
        `${fileBaseName}: multipart form data must end with ${boundary}--: ${JSON.stringify(
          formDataText
        )}`
      );

      const asValue = fileBaseName.replace(/\r\n?|\n/g, "\r\n");
      const asName = asValue.replace(/[\r\n"]/g, encodeURIComponent);
      const asFilename = fileBaseName.replace(/[\r\n"]/g, encodeURIComponent);
      const expectedText = [
        boundary,
        'Content-Disposition: form-data; name="filename"',
        "",
        asValue,
        boundary,
        `Content-Disposition: form-data; name="${asName}"`,
        "",
        "filename",
        boundary,
        `Content-Disposition: form-data; name="file"; ` +
          `filename="${asFilename}"`,
        "Content-Type: text/plain",
        "",
        kTestChars,
        boundary + "--",
      ].join("\r\n");

      assert_true(
        formDataText.startsWith(expectedText),
        `Unexpected multipart-shaped form data received:\n${formDataText}\nExpected:\n${expectedText}`
      );
    }, `Upload ${fileBaseName} (${fileNameSource}) in fetch with FormData`);
  };
  self.formDataPostFileUploadTest = formDataPostFileUploadTest;
}
